package com.springboot.util.img;

import com.springboot.util.img.seal.SealSample;
import lombok.extern.slf4j.Slf4j;
import net.coobird.thumbnailator.Thumbnails;
import org.springframework.stereotype.Component;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.font.FontRenderContext;
import java.awt.geom.AffineTransform;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.io.*;
import java.util.HashMap;
import java.util.Map;

/**
 * 图片处理工具类
 *
 * @description
 * @Author zyj
 * @Date 21:10 2020/4/2
 */
@Slf4j
@Component
public class ImageUtil {
    /**
     * @Description:
     * @Param: [companyName 名称1, legalName 名称2]
     * @return: java.awt.image.BufferedImage
     * @Author: zyj
     * @Date: 2020/9/18
     */
    public BufferedImage generateCustomerSeal(String companyName,String legalName) throws Exception {
        BufferedImage privateSeal = SealSample.privateSeal_5(legalName);
        BufferedImage officialSeal = SealSample.officialSeal_4(companyName);
        privateSeal = zipImage(privateSeal, 144);
//        ImageIO.write(zipImage(mergeImg(privateSeal , officialSeal, 420, -138),200), "png", new FileOutputStream("C:\\Users\\Administrator\\Desktop\\"+companyName+"_"+legalName+".png"));
        return zipImage(mergeImg(privateSeal , officialSeal, 420, -138),200);
    }
    /**
     * @Description:  生成方章
     * @Param: [legalName 名]
     * @return: java.awt.image.BufferedImage
     * @Author: zyj
     * @Date: 2020/8/31
     */
    public BufferedImage generatePrivateSeal(String legalName) throws Exception {
        return SealSample.privateSeal_5(legalName);
    }
    /**
    * @Description: 动态生成圆章
    * @Param: [companeyName 名]
    * @return: java.awt.image.BufferedImage
    * @Author: zyj
    * @Date: 2020/8/31
    */
    public BufferedImage generateOrganSeal(String companyName) throws Exception {
        return SealSample.officialSeal_4(companyName);
    }
    /**
     * 生成图片  签章+签名   图片
     * @param name
     * @param signImage
     * @param x
     * @param y
     * @return java.awt.image.BufferedImage
     * @author zyj
     */
    public  ByteArrayOutputStream generateSignImg(String name,BufferedImage signImage,int x,int y,int zip) throws Exception{
        BufferedImage bufferedImage1 = SealSample.officialSeal(name);
        int rate = 0;
        if (x==0){
            rate = signImage.getWidth();
        }else {
            rate = signImage.getHeight()*2;
        }
        BufferedImage bufferedImage2 = Thumbnails.of(signImage).scale(300.0/rate).asBufferedImage();
        BufferedImage bufferedImage3 = mergeImg(bufferedImage1, bufferedImage2, x, y);
        BufferedImage bufferedImage4 = Thumbnails.of(bufferedImage3).scale(zip/300.0).asBufferedImage();
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        ImageIO.write(bufferedImage4, "png",bos);


        return bos;
    }

    public  ByteArrayOutputStream zipImage(InputStream inputStream, int width) throws Exception {
        BufferedImage bi = ImageIO.read(inputStream);
        int w = bi.getWidth(null);
        double bili = width / (double) w;

        BufferedImage bufferedImage = Thumbnails.of(bi).scale(bili).asBufferedImage();
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        ImageIO.write(bufferedImage, "png", byteArrayOutputStream);
        return byteArrayOutputStream;
    }


    public static void main(String[] args) throws Exception {

        ImageUtil imageUtil = new ImageUtil();
//        BufferedImage bufferedImage = imageUtil.generateCustomerSeal("有限责任公司", "Franci Pauolino Hermene Teodulo ");
//        BufferedImage bufferedImage = imageUtil.generatePrivateSeal("Franci Pauolino Hermene Teodulo ");
        BufferedImage bufferedImage = imageUtil.generateOrganSeal("Franci Pauolino Hermene Teodulo ");


        File outFile = new File("D:\\Download\\ee\\"+System.currentTimeMillis()+".png");
        if (outFile!=null) {
            //输出png图片到指定目录
            ImageIO.write(bufferedImage, "png", outFile);
        }

    }

    /**
     * 压缩图片
     * 根据width等比例压缩
     *
     * @param bufferedImage
     * @param width
     * @return java.awt.image.BufferedImage
     * @author zyj
     */
    public BufferedImage zipImage(BufferedImage bufferedImage, int width) throws Exception {
        int w = bufferedImage.getWidth(null);
        int h = bufferedImage.getHeight(null);
        double bili = width / (double) w;
        int height = (int) (h * bili);

        BufferedImage buffImg = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
        Graphics2D graphics = buffImg.createGraphics();
        graphics.drawImage(bufferedImage.getScaledInstance(width, height, BufferedImage.TYPE_INT_ARGB), 0, 0, null);
        return buffImg;
    }
    //********************** 合并图片 ************************************************************************************


    /**
     * 两图片合并
     * img2 左下角 为 0,0坐标
     *
     * @param img1 图片1
     * @param img2 图片2
     * @param x
     * @param y
     * @return java.awt.image.BufferedImage
     * @author zyj
     */
    public BufferedImage mergeImg(BufferedImage img1, BufferedImage img2, Integer x, Integer y) throws Exception {
        y = -y;
        int x1 = 0, y1 = 0, x2 = 0, y2 = 0;
        //初始化画布
        int width = img2.getWidth(null);
        if (x < 0) {
            width = Math.max(width - x, img1.getWidth(null));
            x1 = 0;
            x2 = Math.abs(x);
        } else {
            width = Math.max(width, img1.getWidth(null) + x);
            x2 = 0;
            x1 = x;
        }
        int height = img2.getHeight(null);
        if (y < 0) {
            height = Math.max(height - y, img1.getHeight(null));
            y1 = 0;
            y2 = Math.abs(y);
        } else {
            height = Math.max(height, y + img1.getHeight(null));
            y2 = 0;
            y1 = y;
        }
        BufferedImage bgImg = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
        Graphics2D g = bgImg.createGraphics();
        //将图片画到画布
        g.drawImage(img1, x1, y1, img1.getWidth(null), img1.getHeight(null), null);
        g.drawImage(img2, x2, y2, img2.getWidth(null), img2.getHeight(null), null);

        g.dispose();
        return bgImg;
    }

    //******************************* CA公章 ****************************************************************************

    /**
     * 生成公章  使用默认参数
     *
     * @param companyName
     * @return java.awt.image.BufferedImage
     * @author zyj
     */
    public byte[] generateSealByte(String companyName) {
        BufferedImage bufferedImage = generateSeal(companyName);
        return imageToBytes(bufferedImage, "png");
    }

    /**
     * BufferedImage转byte[]
     *
     * @param bImage BufferedImage对象
     * @return byte[]
     * @auth zhy
     */
    public byte[] imageToBytes(BufferedImage bImage, String fileType) {
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        try {
            ImageIO.write(bImage, fileType, out);
        } catch (IOException e) {
            log.error(e.getMessage());
        }
        return out.toByteArray();
    }

    /**
     * 生成公章  使用默认参数
     *
     * @param companyName
     * @return java.awt.image.BufferedImage
     * @author zyj
     */
    public BufferedImage generateSeal(String companyName) {
        return generateSeal(200, 200, 40, companyName);
    }




    /**
     * 生成公章
     *
     * @param width       宽
     * @param height      高
     * @param size        字体大小
     * @param companyName 公司名称
     * @return java.awt.image.BufferedImage
     * @author zyj
     */
    public BufferedImage generateSeal(int width, int height, int size, String companyName) {
        // 定义图像buffer
        BufferedImage buffImg = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
        Graphics2D g = buffImg.createGraphics();
        g.setColor(Color.RED);
        //设置锯齿圆滑
        g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

        //绘制圆
        int radius = height / 2;//周半径
        int CENTERX = width / 2;//画图所出位置
        int CENTERY = height / 2;//画图所处位置

        Ellipse2D circle = new Ellipse2D.Double();
        circle.setFrameFromCenter(CENTERX, CENTERY, CENTERX + radius, CENTERY + radius);
        g.draw(circle);

        //绘制中间的五角星
        g.setFont(new Font("宋体", Font.BOLD, 60));
        g.drawString("★", CENTERX - (40 / 2), CENTERY + (40 / 3));

//        //添加姓名
//        g.setFont(new Font("宋体", Font.LAYOUT_LEFT_TO_RIGHT, 30));// 写入签名
//        g.drawString(centerName, CENTERX -(40), CENTERY +(30+50));
//
//        //添加年份
//        g.setFont(new Font("宋体", Font.LAYOUT_LEFT_TO_RIGHT, 20));// 写入签名
//        g.drawString(year, CENTERX -(60), CENTERY +(30+80));


        //根据输入字符串得到字符数组
        String[] messages = companyName.split("", 0);
        //输入的字数
        int ilength = messages.length;

        //设置字体属性
        Font f = new Font("Serif", Font.BOLD, size);

        FontRenderContext context = g.getFontRenderContext();
        Rectangle2D bounds = f.getStringBounds(companyName, context);

        //字符宽度＝字符串长度/字符数
        double char_interval = (bounds.getWidth() / ilength);
        //上坡度
        double ascent = -bounds.getY();

        int first = 0, second = 0;
        boolean odd = false;
        if (ilength % 2 == 1) {
            first = (ilength - 1) / 2;
            odd = true;
        } else {
            first = (ilength) / 2 - 1;
            second = (ilength) / 2;
            odd = false;
        }

        double radius2 = radius - ascent;
        double x0 = CENTERX;
        double y0 = CENTERY - radius + ascent;
        //旋转角度
        double a = 2 * Math.asin(char_interval / (2 * radius2));

        if (odd) {
            g.setFont(f);
            g.drawString(messages[first], (float) (x0 - char_interval / 2), (float) y0);

            //中心点的右边
            for (int i = first + 1; i < ilength; i++) {
                double aa = (i - first) * a;
                double ax = radius2 * Math.sin(aa);
                double ay = radius2 - radius2 * Math.cos(aa);
                drawStringRight(g, f, aa, messages[i], (float) (x0 + ax - char_interval / 2 * Math.cos(aa)), (float) (y0 + ay - char_interval / 2 * Math.sin(aa)));
            }
            //中心点的左边
            for (int i = first - 1; i > -1; i--) {
                double aa = (first - i) * a;
                double ax = radius2 * Math.sin(aa);
                double ay = radius2 - radius2 * Math.cos(aa);
                drawStringLeft(g, f, aa, messages[i], (float) (x0 - ax - char_interval / 2 * Math.cos(aa)), (float) (y0 + ay + char_interval / 2 * Math.sin(aa)));
            }

        } else {
            //中心点的右边
            for (int i = second; i < ilength; i++) {
                double aa = (i - second + 0.5) * a;
                double ax = radius2 * Math.sin(aa);
                double ay = radius2 - radius2 * Math.cos(aa);
                drawStringRight(g, f, aa, messages[i], (float) (x0 + ax - char_interval / 2 * Math.cos(aa)), (float) (y0 + ay - char_interval / 2 * Math.sin(aa)));
            }

            //中心点的左边
            for (int i = first; i > -1; i--) {
                double aa = (first - i + 0.5) * a;
                double ax = radius2 * Math.sin(aa);
                double ay = radius2 - radius2 * Math.cos(aa);
                drawStringLeft(g, f, aa, messages[i], (float) (x0 - ax - char_interval / 2 * Math.cos(aa)), (float) (y0 + ay + char_interval / 2 * Math.sin(aa)));
            }
        }
        return buffImg;
    }
    public BufferedImage generateSeal_2(int width, int height, int size, String companyName) {
        // 定义图像buffer
        BufferedImage buffImg = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
        Graphics2D g = buffImg.createGraphics();
        g.setColor(Color.RED);
        //设置锯齿圆滑
        g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

        //绘制圆
        int radius = height / 2;//周半径
        int CENTERX = width / 2;//画图所出位置
        int CENTERY = height / 2;//画图所处位置

        Ellipse2D circle = new Ellipse2D.Double();
        circle.setFrameFromCenter(CENTERX, CENTERY, CENTERX + radius, CENTERY + radius);
        g.draw(circle);

        //绘制中间的五角星
        g.setFont(new Font("宋体", Font.BOLD, 114));
        g.drawString("★", CENTERX - (76 / 2), CENTERY + (76 / 3));

//        //添加姓名
//        g.setFont(new Font("宋体", Font.LAYOUT_LEFT_TO_RIGHT, 30));// 写入签名
//        g.drawString(centerName, CENTERX -(40), CENTERY +(30+50));
//
//        //添加年份
//        g.setFont(new Font("宋体", Font.LAYOUT_LEFT_TO_RIGHT, 20));// 写入签名
//        g.drawString(year, CENTERX -(60), CENTERY +(30+80));


        //根据输入字符串得到字符数组
        String[] messages = companyName.split("", 0);
        //输入的字数
        int ilength = messages.length;

        //设置字体属性
        Font f = new Font("Serif", Font.BOLD, size);

        FontRenderContext context = g.getFontRenderContext();
        Rectangle2D bounds = f.getStringBounds(companyName, context);

        //字符宽度＝字符串长度/字符数
        double char_interval = (bounds.getWidth() / ilength);
        //上坡度
        double ascent = -bounds.getY();

        int first = 0, second = 0;
        boolean odd = false;
        if (ilength % 2 == 1) {
            first = (ilength - 1) / 2;
            odd = true;
        } else {
            first = (ilength) / 2 - 1;
            second = (ilength) / 2;
            odd = false;
        }

        double radius2 = radius - ascent;
        double x0 = CENTERX;
        double y0 = CENTERY - radius + ascent;
        //旋转角度
        double a = 2 * Math.asin(char_interval / (2 * radius2));

        if (odd) {
            g.setFont(f);
            g.drawString(messages[first], (float) (x0 - char_interval / 2), (float) y0);

            //中心点的右边
            for (int i = first + 1; i < ilength; i++) {
                double aa = (i - first) * a;
                double ax = radius2 * Math.sin(aa);
                double ay = radius2 - radius2 * Math.cos(aa);
                drawStringRight(g, f, aa, messages[i], (float) (x0 + ax - char_interval / 2 * Math.cos(aa)), (float) (y0 + ay - char_interval / 2 * Math.sin(aa)));
            }
            //中心点的左边
            for (int i = first - 1; i > -1; i--) {
                double aa = (first - i) * a;
                double ax = radius2 * Math.sin(aa);
                double ay = radius2 - radius2 * Math.cos(aa);
                drawStringLeft(g, f, aa, messages[i], (float) (x0 - ax - char_interval / 2 * Math.cos(aa)), (float) (y0 + ay + char_interval / 2 * Math.sin(aa)));
            }

        } else {
            //中心点的右边
            for (int i = second; i < ilength; i++) {
                double aa = (i - second + 0.5) * a;
                double ax = radius2 * Math.sin(aa);
                double ay = radius2 - radius2 * Math.cos(aa);
                drawStringRight(g, f, aa, messages[i], (float) (x0 + ax - char_interval / 2 * Math.cos(aa)), (float) (y0 + ay - char_interval / 2 * Math.sin(aa)));
            }

            //中心点的左边
            for (int i = first; i > -1; i--) {
                double aa = (first - i + 0.5) * a;
                double ax = radius2 * Math.sin(aa);
                double ay = radius2 - radius2 * Math.cos(aa);
                drawStringLeft(g, f, aa, messages[i], (float) (x0 - ax - char_interval / 2 * Math.cos(aa)), (float) (y0 + ay + char_interval / 2 * Math.sin(aa)));
            }
        }
        return buffImg;
    }

    /**
     * 中心点左写字
     *
     * @param g
     * @param f
     * @param aa
     * @param message
     * @param x
     * @param y
     * @return void
     * @author zyj
     */
    private void drawStringLeft(Graphics2D g, Font f, double aa, String message, float x, float y) {
        AffineTransform transform = AffineTransform.getRotateInstance(-aa);//,x0 + ax, y0 + ay);
        Font f2 = f.deriveFont(transform);
        g.setFont(f2);
        g.drawString(message, x, y);
    }

    /**
     * 中心点左写字
     *
     * @param g
     * @param f
     * @param aa
     * @param message
     * @param x
     * @param y
     * @return void
     * @author zyj
     */
    private void drawStringRight(Graphics2D g, Font f, double aa, String message, float x, float y) {
        AffineTransform transform = AffineTransform.getRotateInstance(aa);//,x0 + ax, y0 + ay);
        Font f2 = f.deriveFont(transform);
        g.setFont(f2);
        g.drawString(message, x, y);
    }


    /**
     * 根据文字生成图片流
     * @根据指定的str去生成图片
     */
    public byte[] strTextSealByte(String companyName) {
        try {
            BufferedImage bufferedImage = createTextImage(companyName);
            return imageToBytes(bufferedImage, "png");
        } catch (Exception e){
            log.error("根据文字生成图片失败",e);
            return null;
        }

    }

    /**
     * 根据文字生成图片
     * @根据指定的str去生成图片
     */
    private  BufferedImage createTextImage(String str) throws Exception{
        Font font=new Font("宋体",Font.BOLD,18);
        //获取font的样式应用在str上的整个矩形
        Rectangle2D r=font.getStringBounds(str, new FontRenderContext(AffineTransform.getScaleInstance(1, 1),false,false));
        //获取单个字符的高度
        int unitHeight=(int)Math.floor(r.getHeight());
        //获取整个str用了font样式的宽度这里用四舍五入后+1保证宽度绝对能容纳这个字符串作为图片的宽度
        int width=(int)Math.round(r.getWidth())+1;
        //把单个字符的高度+3保证高度绝对能容纳字符串作为图片的高度
        int height=unitHeight+3;
        //创建图片
        BufferedImage image=new BufferedImage(width,height,BufferedImage.TYPE_INT_BGR);
        Graphics g=image.getGraphics();
        g.setColor(Color.WHITE);
        //先用白色填充整张图片,也就是背景
        g.fillRect(0, 0, width, height);
        //在换成黑色
        g.setColor(Color.black);
        //设置画笔字体
        g.setFont(font);
        //画出字符串
        g.drawString(str, 0, font.getSize());
        g.dispose();


//        File outFile = new File("C:\\Users\\asus\\Desktop\\ee"+System.currentTimeMillis()+".png");
//        if (outFile!=null) {
//            //输出png图片到指定目录
//            ImageIO.write(image, "png", outFile);
//        }
//        //返回数据流
//        ByteArrayOutputStream out = new ByteArrayOutputStream();
//        boolean flag = ImageIO.write(image, "png", out);
//        byte[] b = out.toByteArray();

        return image;
    }

    /**
     * @describe: 根据文字生成图片(红色字体)
     * @param:  [str]
     * @return: java.awt.image.BufferedImage
     * @author: zyj
     * @date: 2021/3/10
     */
    public BufferedImage createStrImage(String str) throws Exception {
        try {
            Font font = new Font("宋体", Font.BOLD, 14);
            String[] strArr = str.split("\n");
            //设定图片宽度和高度
            int width = 176;
            int height = 50;
            //创建图片
            BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_BGR);
            Graphics g = image.getGraphics();
            g.setClip(0, 0, width, height);
            g.setColor(Color.WHITE);
            //先用白色填充整张图片,也就是背景
            g.fillRect(0, 0, width, height);
            //在换成红色
            g.setColor(Color.red);
            //设置画笔字体
            g.setFont(font);
            //字体高度
            int fontHeight = (int) font.getSize2D();
            //得到当前的font metrics
            FontMetrics fontMetrics = g.getFontMetrics(font);
            // 字符串长度（像素） str要打印的字符串
            int strPixelWidth = fontMetrics.stringWidth(str);
            // 算出行数
            int lineSize = (int) Math.ceil(strPixelWidth * 1.0 / width);
            if (width < strPixelWidth) {
                StringBuilder sb = new StringBuilder();
                int j = 0;
                int tempStart = 0;
                String tempStrs[] = new String[lineSize];// 存储换行之后每一行的字符串
                for (int i1 = 0; i1 < str.length(); i1++) {
                    char ch = str.charAt(i1);
                    sb.append(ch);
                    Rectangle2D bounds2 = fontMetrics.getStringBounds(sb.toString(), null);
                    int tempStrPi1exlWi1dth = (int) bounds2.getWidth();
                    if (tempStrPi1exlWi1dth > width) {
                        tempStrs[j++] = str.substring(tempStart, i1);
                        tempStart = i1;
                        sb.delete(0, sb.length());
                        sb.append(ch);
                    }
                    if (i1 == str.length() - 1) {// 最后一行
                        tempStrs[j] = str.substring(tempStart);
                    }
                }
                //画出字符串
                for (int i = 0; i < tempStrs.length; i++) {
                    g.drawString(tempStrs[i], 5, (fontHeight + 5) * (i + 1));
                }
            } else {
                g.drawString(str, 5, fontHeight);
            }
            g.dispose();
            return image;
        } catch (Exception e) {
            e.printStackTrace();
            log.error("根据文字生成图片失败");
        }
        return null;
    }


    /**
     * 方法描述 获取图片宽高
     * @since: 1.0
     * @param is
     * @return: Map  height:高   width：宽
     * @author: zyj
     * @date: 2023/5/31 17:01
     */
    public Map<String, Integer> processStream(InputStream is) throws IOException {
        int c1 = is.read();
        int c2 = is.read();
        int c3 = is.read();
        Map<String, Integer> result = new HashMap<>();
        int height=0;
        int width=0;

        String  mimeType = null;
        width = height = -1;

        if (c1 == 'G' && c2 == 'I' && c3 == 'F') { // GIF
            is.skip(3);
            width = readInt(is,2,false);
            height = readInt(is,2,false);
            mimeType = "image/gif";
        } else if (c1 == 0xFF && c2 == 0xD8) { // JPG
            while (c3 == 255) {
                int marker = is.read();
                int len = readInt(is,2,true);
                if (marker == 192 || marker == 193 || marker == 194) {
                    is.skip(1);
                    height = readInt(is,2,true);
                    width = readInt(is,2,true);
                    mimeType = "image/jpeg";
                    break;
                }
                is.skip(len - 2);
                c3 = is.read();
            }
        } else if (c1 == 137 && c2 == 80 && c3 == 78) { // PNG
            is.skip(15);
            width = readInt(is,2,true);
            is.skip(2);
            height = readInt(is,2,true);
            mimeType = "image/png";
        } else if (c1 == 66 && c2 == 77) { // BMP
            is.skip(15);
            width = readInt(is,2,false);
            is.skip(2);
            height = readInt(is,2,false);
            mimeType = "image/bmp";
        } else {
            int c4 = is.read();
            if ((c1 == 'M' && c2 == 'M' && c3 == 0 && c4 == 42)
                    || (c1 == 'I' && c2 == 'I' && c3 == 42 && c4 == 0)) { //TIFF
                boolean bigEndian = c1 == 'M';
                int ifd = 0;
                int entries;
                ifd = readInt(is,4,bigEndian);
                is.skip(ifd - 8);
                entries = readInt(is,2,bigEndian);
                for (int i = 1; i <= entries; i++) {
                    int tag = readInt(is,2,bigEndian);
                    int fieldType = readInt(is,2,bigEndian);
                    int valOffset;
                    if ((fieldType == 3 || fieldType == 8)) {
                        valOffset = readInt(is,2,bigEndian);
                        is.skip(2);
                    } else {
                        valOffset = readInt(is,4,bigEndian);
                    }
                    if (tag == 256) {
                        width = valOffset;
                    } else if (tag == 257) {
                        height = valOffset;
                    }
                    if (width != -1 && height != -1) {
                        mimeType = "image/tiff";
                        break;
                    }
                }
            }
        }
        if (mimeType == null) {
            throw new IOException("Unsupported image type");
        }

        result.put("height", height);
        result.put("width", width);

        return result;
    }

    private int readInt(InputStream is, int noOfBytes, boolean bigEndian) throws IOException {
        int ret = 0;
        int sv = bigEndian ? ((noOfBytes - 1) * 8) : 0;
        int cnt = bigEndian ? -8 : 8;
        for(int i=0;i<noOfBytes;i++) {
            ret |= is.read() << sv;
            sv += cnt;
        }
        return ret;
    }

}
